package cn.jeefast.rest.upload;

import cn.jeefast.common.exception.RRException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 秦单单的公众方法
 */
@Slf4j
public class QDUtil {

    @Autowired
    private HttpServletRequest request;



    /**
     *  验证是否为身份证号码
     * @param shipperCardNumber  身份证号码
     */
    public static void isCard(String shipperCardNumber) {
        String str = "[1-9]{2}[0-9]{4}(19|20)[0-9]{2}"
                + "((0[1-9]{1})|(1[1-2]{1}))((0[1-9]{1})|([1-2]{1}[0-9]{1}|(3[0-1]{1})))"
                + "[0-9]{3}[0-9x]{1}";

        Pattern pattern = Pattern.compile(str);
        if(!pattern.matcher(shipperCardNumber).matches()){
//            log.error("身份证号号码错误！");
            throw new RRException("你输入的身份证号码错误！");
        }

    }

    /**
     *  是否有效手机号
     * @param phone  手机号码
     */
    public static void isPhone(String phone) {
        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
        if (phone.length() != 11) {
//            log.error("手机号错误！");
            throw new RRException("您输入的手机号有误！");
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (!isMatch) {
//                log.error("手机号错误！");
                throw new RRException("您输入的手机号有误！");
            }
        }
    }
   /* *//**
     *  是否有效手机号
     * @param phone  手机号码
     *//*
    public static void isPhone1(String phone) {
        String regex = "^1[3|4|5|7|8][0-9]\\\\d{4,8}$";
        if (phone.length() != 11) {
            log.error("手机号错误！");
            throw new RRException("您输入的手机号有误！");
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (!isMatch) {
                log.error("手机号错误！");
                throw new RRException("您输入的手机号有误！");
            }
        }
    }*/


    /**
     *  生成随即数方法
     * @param length  生成随机数长度
     * @return
     */
    public static String Generated(int length){
        String str = "0123456789";
        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            //public int nextInt(int n) 该方法的作用是生成一个随机的int值，该值介于[0,n)的区间，也就是0到n之间的随机int值，包含0而不包含n。
            char ch=str.charAt(new Random().nextInt(str.length()));
            sb.append(ch);
        }
        System.out.println(sb.toString());
        return sb.toString();
    }

    /**
     *  生成字母+随即数方法
     * @param LetLength  字母长度
     * @return
     */
    public static String lettersAndNum(int LetLength){
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuffer letSb = new StringBuffer();
        for ( int i = 0; i < LetLength; i++ )
        {
            int number = random.nextInt( base.length() );
            letSb.append( base.charAt( number ) );
        }
        return letSb.toString();
    }

    /**
     *  生成随即数+字母方法
     * @param numLength  数字长度
     * @param LetLength  字母长度
     * @return
     */
    public static String numAndLetters(int numLength,int LetLength){
        String str = "123456789";
        StringBuilder sb = new StringBuilder(numLength);
        for (int i = 0; i < numLength; i++) {
            //public int nextInt(int n) 该方法的作用是生成一个随机的int值，该值介于[0,n)的区间，也就是0到n之间的随机int值，包含0而不包含n。
            char ch=str.charAt(new Random().nextInt(str.length()));
            sb.append(ch);
        }
        System.out.println(sb.toString());
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Random random = new Random();
        StringBuffer letSb = new StringBuffer();
        for ( int i = 0; i < LetLength; i++ )
        {
            int number = random.nextInt( base.length() );
            letSb.append( base.charAt( number ) );
        }


        return sb.toString()+letSb.toString();
    }

    /**
     * 几分钟之后的时间
     * @param Minute  分钟数
     * @return
     */
    public static Date afterTime(int Minute){
        Calendar c = Calendar.getInstance();//实例化
        System.out.println(c.getTime());//输出为当前时间
        c.add(Calendar.MINUTE, Minute);// +分钟
        System.out.println(c.getTime());//输出为+分钟分钟时间
        return c.getTime();
    }


    /**
     * 几分钟之前的时间
     * @param Minute  分钟数
     * @return
     */
    public static Date beforeTime(int Minute){
        Calendar c = Calendar.getInstance();//实例化
        System.out.println(c.getTime());//输出为当前时间
        c.add(Calendar.MINUTE, -Minute);//
        System.out.println(c.getTime());//输出为+3分钟时间
        return c.getTime();
    }

    /**
     * 几天之后的时间
     * @param day  天
     * @return
     */
    public static Date afterDayTime(int day){
        Calendar c = Calendar.getInstance();//实例化
        System.out.println(c.getTime());//输出为当前时间
        c.set(Calendar.DATE,c.get(Calendar.DATE)+day);
        System.out.println(c.getTime());//输出为+分钟分钟时间
        return c.getTime();
    }



    /**
     * 判断字符串是否为空  空返回true  非空返回false
     * @param str  字符串
     * @return
     */
    public static boolean isBlank(String str) {
        if (null != str && str != null ) {
            str = str.trim();
        } else {
            return true;
        }
        if(str.equals("null")||("null").equals(str)||str.equals("")){
            return true;
        }
        if (null == str || str.length() == 0) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * 判断obj是否为空  空返回true  非空返回false
     * @param obj
     * @return
     */
    public static boolean isBlank(Object obj) {
        if (obj == null) return true;
        else if (obj instanceof CharSequence) return ((CharSequence) obj).length() == 0;
        else if (obj instanceof Collection) return ((Collection) obj).isEmpty();
        else if (obj instanceof Map) return ((Map) obj).isEmpty();
        else if (obj.getClass().isArray()) return Array.getLength(obj) == 0;

        return false;
    }

    /**
     * 判断字符串是否超过最大长度
     * @param str       字符串
     * @param lenght    最大长度
     */
    public static void strMaximum(String str,String returnStr,Integer lenght) {
        if(str==null){
//            log.error("判断字符串是否超过最大长度，字符串不能为空");
            throw new RRException("字符串不能为空！");
        }
        if(isBlank(String.valueOf(lenght))){
//            log.error("判断字符串是否超过最大长度，字符串长度不能为空");
            throw new RRException("字符串长度不能为空！");
        }
        if(str.length()>lenght){
//            log.error("判断字符串是否超过最大长度，字符串长度超过最大限制");
            throw new RRException( returnStr + "超过最大限制！");
        }
    }

    /**
     * Date转LocalDateTime
     * @param date
     * @return
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }
    /**
     * String 转 LocalDateTime
     * @param str
     * @return
     */
    public static LocalDateTime toLocalDateTime(String str) {
        DateTimeFormatter dateTimeFormatter2=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//严格遵守大小写<br>
        return LocalDateTime.parse(str,dateTimeFormatter2);
    }

    /**
     * LocalDateTime转换为Date
     * @param time
     * @return
     */
    public static Date toDate(LocalDateTime time) {
        return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * LocalDateTime转换为String
     * @param time
     * @return
     */
    public static String toStr(LocalDateTime time,Integer num) {
        if(time==null){
//            log.error("LocalDateTime转换为String！");
            throw new RRException("时间不能为空！");
        }
        Date date = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
        return dateToString(date,num);
    }


    /**
     * Date转String
     * @param date      date
     * @param format    显示格式    1：yyyy-MM-dd
     *                               2：yyyy-MM-dd HH:mm:ss
     *                               3：yyyy年MM月dd日 HH:mm:ss
     *                               4: yyyy-MM
     *                               5: MM-dd HH:mm
     *                               6: yyyy-MM-dd HH:mm
     *                               7: HH:mm
     * @return
     */
    public static String dateToString(Date date,Integer format){
        if(date==null){
//            log.error("Date转String！");
            throw new RRException("时间不能为空！");
        }
        if(format==null){
//            log.error("Date转String！");
            throw new RRException("显示格式不能为空！");
        }
        String returnStr = "";
        switch(format){
            case 1:
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 2:
                sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 3:
                sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 4:
                sdf = new SimpleDateFormat("yyyy-MM");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 5:
                sdf = new SimpleDateFormat("MM-dd HH:mm");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 6:
                sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 7:
                sdf = new SimpleDateFormat("HH:mm");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 8:
                sdf = new SimpleDateFormat("yyyy.MM.dd");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 9:
                sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 10:
                sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 11:
                sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
            case 12:
                sdf = new SimpleDateFormat("yyyy年MM月dd日");
                System.out.println(sdf.format(date));
                returnStr = sdf.format(date);
                break;
        }
       return returnStr;
    }

    /**
     * 判断两个时间是否为同一年
     * @param d1    时间1
     * @param d2    时间2
     * @return
     */
    public static boolean sameDate(Date d1, Date d2){
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy");
        return fmt.format(d1).equals(fmt.format(d2));
    }

    public static String reckonLocalDate(LocalDateTime d){

        LocalDateTime end = LocalDateTime.now();
        Duration duration = Duration.between(d,end);
        if(duration.toMinutes()<1){
            return "刚刚";
        }else if(duration.toMinutes()>=1 && duration.toMinutes()<59){
            return duration.toMinutes() +"分钟前";
        }else if(duration.toMinutes()>=60 && duration.toDays()< 1 ){
            return duration.toHours() + "小时前";
        }else {
            return toStr(d,1);
        }
    }




    /**
     * 进行加法运算
     */
    public static double add(double d1, double d2, int len) { // 进行加法运算
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return round(b1.add(b2).doubleValue(),len);
    }

    /**
     * 进行减法运算
     */
    public static double sub(double d1, double d2, int len) { // 进行减法运算
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return round(b1.subtract(b2).doubleValue(),len);
    }

    /**
     * 进行乘法运算
     */
    public static double mul(double d1, double d2, int len) { //
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return round(b1.multiply(b2).doubleValue(),len);
    }

    /**
     * 进行除法运算
     */
    public static double div(double d1, double d2, int len) {// 进行除法运算
        BigDecimal b1 = new BigDecimal(d1);
        BigDecimal b2 = new BigDecimal(d2);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     *	进行四舍五入操作
     */
    public static double round(double d, int len) { // 进行四舍五入操作
        BigDecimal b1 = new BigDecimal(d);
        BigDecimal b2 = new BigDecimal(1);
        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 进行舍尾操作
     */
    public static double rejection(double d, int len) { // 取整
        BigDecimal b1 = new BigDecimal(d);
        BigDecimal b2 = new BigDecimal(1);
        return b1.divide(b2, len, BigDecimal.ROUND_DOWN).doubleValue();
    }


    /**
     * 获取本机ip
     * @return
     */
    public static String getIp(){
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String ip=addr.getHostAddress();//获得本机IP
        System.out.println(ip);
        return ip;
    }
    /**
     * 返回: http://ip:端口+项目名
     */
    public static String getBasePath(HttpServletRequest request) {
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
        return basePath;
    }
    /**
     * 返回: http://localhost:8081 地址
     */
    public static String getNginxPath(HttpServletRequest request) {
        String basePath = request.getScheme() + "://" + request.getServerName() + ":8166" ;
        return basePath;
    }

    /**
     * double转String 保留整数
     * @param d
     * @return
     */
    public static String doubleToString(double d){
       // DecimalFormat df = new DecimalFormat("#,###.00");
        DecimalFormat df = new DecimalFormat("###.00");
        String returnStr = new String();
        if(d == 0){
            returnStr = "0";
        }else{
            returnStr = df.format(d);
            returnStr = returnStr.substring(0,returnStr.indexOf("."));
        }
        return returnStr;
    }
    /**
     * 处理double类型末尾的0
     *
     */
    public static String subZeroAndDot(String s) {
        if (isBlank(s)) {
            throw new RRException("传入值为空");
        }
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");//去掉多余的0
            s = s.replaceAll("[.]$", "");//如最后一位是.则去掉
        }
        return s;
    }


}

